home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Scene 96
/
Scene 96 International Edition (Zyklop Software) (Disc 2) (1997).iso
/
misc
/
coding
/
cp2dekit
/
samples
/
xmpplay.cpp
< prev
Wrap
C/C++ Source or Header
|
1996-12-29
|
13KB
|
546 lines
//***************************************************************************
//
// this file is (c) '94-'96 Niklas Beisert
//
// this file is part of the cubic player development kit.
// you may only use/modify/spread this file under the terms stated
// in the cubic player development kit accompanying documentation.
//
//***************************************************************************
// interface example
#include <time.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
#include "pfilesel.h"
#include "mcp.h"
#include "psetting.h"
#include "binfile.h"
#include "dpmi.h"
#include "poutput.h"
#include "err.h"
#include "plinkman.h"
#include "deviwave.h"
#include "cpiface.h"
#include "xmplay.h"
#include "gmdinst.h"
extern int plLoopMods;
static xmodule mod;
void mcpDrawGStrings(short (*)[132]);
void mcpNormalize();
int mcpSetProcessKey(unsigned short);
static instrument *insts;
static sample *samps;
static int xmpProcessKey(unsigned short key)
{
if (mcpSetProcessKey(key))
return 1;
if (mcpProcessKey)
{
int ret=mcpProcessKey(key);
if (ret==2)
cpiResetScreen();
if (ret)
return 1;
}
int pat,row,p;
switch (key)
{
case 'p': case 'P': case 0x10:
mcpSet(-1, mcpMasterPause, plPause^=1);
plChanChanged=1;
break;
case 0x7700: //ctrl-home
gmdInstClear();
xmpSetPos(0, 0);
break;
case 0x7300: //ctrl-left
p=xmpGetPos();
pat=p>>8;
xmpSetPos(pat-1, 0);
break;
case 0x7400: //ctrl-right
p=xmpGetPos();
pat=p>>8;
xmpSetPos(pat+1, 0);
break;
case 0x8D00: // ctrl-up
p=xmpGetPos();
pat=p>>8;
row=p&0xFF;
xmpSetPos(pat, row-8);
break;
case 0x9100: //ctrl-down
p=xmpGetPos();
pat=p>>8;
row=p&0xFF;
xmpSetPos(pat, row+8);
break;
}
return 1;
}
static int xmpLooped()
{
return !plLoopMods&&xmpLoop();
}
static void xmpIdle()
{
xmpSetLoop(plLoopMods);
if (mcpIdle)
mcpIdle();
}
static void xmpDrawGStrings(short (*buf)[132])
{
writestring(buf[0], 0, 0, "", 132);
writestring(buf[1], 0, 0, "", 132);
writestring(buf[2], 0, 0, "", 132);
mcpDrawGStrings(buf);
writenum(buf[2], 2, 0x07, xmpGetPos(), 16, 4, 0);
writenum(buf[2], 8, 0x07, mcpGet(-1, mcpGTimer), 16, 8, 0);
}
static void xmpCloseFile()
{
xmpStopModule();
xmpFreeModule(mod);
}
//**********************************************************************
static void xmpMarkInsSamp(char *ins, char *smp)
{
int i;
for (i=0; i<plNLChan; i++)
{
if (!xmpChanActive(i))
continue;
int in=xmpGetChanIns(i);
int sm=xmpGetChanSamp(i);
ins[in-1]=((plSelCh==i)||(ins[in-1]==3))?3:2;
smp[sm]=((plSelCh==i)||(smp[sm]==3))?3:2;
}
}
//**********************************************************************
static int patwidth;
static int patheight;
static int patfirst;
static void xmpDrawPattern(int sel)
{
unsigned short xmpos=xmpGetPos();
int ord=xmpos>>8;
int pat=mod.orders[ord];
int row=xmpos&0xFF;
int ch=plSelCh;
int row0=row-patheight/3;
int patlen=mod.patlens[pat];
int i;
for (i=0; i<patheight; i++)
{
int r=row0+i;
short buf[132];
writestring(buf, 0, 0, "", patwidth);
if ((r>=0)&&(r<patlen))
{
unsigned char *fx=mod.patterns[pat][mod.nchan*r+ch];
writestring(buf, 0, 0x08, "·· ·· ·· ·· ··", 16);
if (fx[0])
writenum(buf, 0, 0x07, fx[0], 16, 2, 0);
if (fx[1])
writenum(buf, 3, 0x07, fx[1], 16, 2, 0);
if (fx[2])
writenum(buf, 7, 0x07, fx[2], 16, 2, 0);
if (fx[3]||fx[4])
{
writenum(buf, 11, 0x07, fx[3], 16, 2, 0);
writenum(buf, 14, 0x07, fx[4], 16, 2, 0);
}
}
int j;
if (r==row)
for (j=0; j<patwidth; j++)
buf[j]|=0x8800;
displaystrattr(patfirst+i, 0, buf, patwidth);
}
}
static void TrakSetWin(int xpos, int wid, int ypos, int hgt)
{
patfirst=ypos;
patheight=hgt;
patwidth=wid;
}
static int TrakGetWin(cpitextmodequerystruct &q)
{
if (!plTrackActive)
return 0;
q.hgtmin=3;
q.hgtmax=100;
q.xmode=1;
q.size=2;
q.top=0;
q.killprio=64;
q.viewprio=160;
return 1;
}
static int TrakIProcessKey(unsigned short key)
{
switch (key)
{
case 't': case 'T':
cpiTextSetMode("trak");
break;
case 'x': case 'X':
plTrackActive=1;
return 0;
case 0x2d00: //alt-x
plTrackActive=0;
return 0;
default:
return 0;
}
return 1;
}
static int TrakAProcessKey(unsigned short key)
{
switch (key)
{
case 't': case 'T':
plTrackActive=!plTrackActive;
cpiTextRecalc();
break;
}
return 1;
}
static int trkEvent(int ev)
{
return 1;
}
static cpitextmoderegstruct xmpTrakMode = {"trak", TrakGetWin, TrakSetWin, xmpDrawPattern, TrakIProcessKey, TrakAProcessKey, trkEvent};
//************************************************************************
static void logvolbar(int &l, int &r)
{
if (l>32)
l=32+((l-32)>>1);
if (l>48)
l=48+((l-48)>>1);
if (l>56)
l=56+((l-56)>>1);
if (l>64)
l=64;
if (r>32)
r=32+((r-32)>>1);
if (r>48)
r=48+((r-48)>>1);
if (r>56)
r=56+((r-56)>>1);
if (r>64)
r=64;
}
static void drawvolbar(short *buf, int i, unsigned char st)
{
int l,r;
xmpGetRealVolume(i, l, r);
logvolbar(l, r);
l=(l+4)>>3;
r=(r+4)>>3;
if (plPause)
l=r=0;
if (st)
{
writestring(buf, 8-l, 0x08, "■■■■■■■■", l);
writestring(buf, 9, 0x08, "■■■■■■■■", r);
}
else
{
writestringattr(buf, 8-l, "■\x0F■\x0B■\x0B■\x09■\x09■\x01■\x01■\x01"+16-l-l, l);
writestringattr(buf, 9, "■\x01■\x01■\x01■\x09■\x09■\x0B■\x0B■\x0F", r);
}
}
static void drawlongvolbar(short *buf, int i, unsigned char st)
{
int l,r;
xmpGetRealVolume(i, l, r);
logvolbar(l, r);
l=(l+2)>>2;
r=(r+2)>>2;
if (plPause)
l=r=0;
if (st)
{
writestring(buf, 16-l, 0x08, "■■■■■■■■■■■■■■■■", l);
writestring(buf, 17, 0x08, "■■■■■■■■■■■■■■■■", r);
}
else
{
writestringattr(buf, 16-l, "■\x0F■\x0F■\x0B■\x0B■\x0B■\x0B■\x09■\x09■\x09■\x09■\x01■\x01■\x01■\x01■\x01■\x01"+32-l-l, l);
writestringattr(buf, 17, "■\x01■\x01■\x01■\x01■\x01■\x01■\x09■\x09■\x09■\x09■\x0B■\x0B■\x0B■\x0B■\x0F■\x0F", r);
}
}
static void drawchannel(short *buf, int len, int i)
{
unsigned char st=plMuteCh[i];
unsigned char tcol=st?0x08:0x0F;
unsigned char tcold=st?0x08:0x07;
unsigned char tcolr=st?0x08:0x0B;
switch (len)
{
case 36:
writestring(buf, 0, tcold, " -- --- -- ------ ········ ········ ", 36);
break;
case 62:
writestring(buf, 0, tcold, " ---· --· -· ------ ········ ········ ", 62);
break;
case 128:
writestring(buf, 0, tcold, " │ │ │ │ │ │ ················ ················", 128);
break;
case 76:
writestring(buf, 0, tcold, " │ │ │ │ │ ········ ········", 76);
break;
case 44:
writestring(buf, 0, tcold, " -- ---· --· -· ------ ········ ········ ", 44);
break;
}
if (!xmpChanActive(i))
return;
int ins=xmpGetChanIns(i);
int smp=xmpGetChanSamp(i);
switch (len)
{
case 36:
writenum(buf, 1, tcol, ins, 16, 2, 0);
/*
writestring(buf, 4, ci.notehit?tcolr:tcol, plNoteStr[ci.note], 3);
writenum(buf, 8, tcol, ci.vol, 16, 2, 0);
char *fxstr=getfxstr6(ci.fx);
if (fxstr)
writestring(buf, 11, tcol, fxstr, 6);
*/
drawvolbar(buf+18, i, st);
break;
case 62:
if (ins)
if (*insts[ins-1].name)
writestring(buf, 1, tcol, insts[ins-1].name, 21);
else
{
writestring(buf, 1, 0x08, "( )", 4);
writenum(buf, 2, 0x08, ins, 16, 2, 0);
}
/*
writestring(buf, 24, ci.notehit?tcolr:tcol, plNoteStr[ci.note], 3);
writestring(buf, 27, tcol, ci.pitchslide?" \x18\x19\x0D\x18\x19\x0D"+ci.pitchslide:" ~≡"+ci.pitchfx, 1);
writenum(buf, 29, tcol, ci.vol, 16, 2, 0);
writestring(buf, 31, tcol, ci.volslide?" \x18\x19\x18\x19"+ci.volslide:" ~"+ci.volfx, 1);
writestring(buf, 33, tcol, "L123456MM9ABCDER"+(ci.pan>>4), 1);
writestring(buf, 34, tcol, " \x1A\x1B"+ci.panslide, 1);
char *fxstr=getfxstr6(ci.fx);
if (fxstr)
writestring(buf, 36, tcol, fxstr, 6);
*/
drawvolbar(buf+44, i, st);
break;
case 76:
if (ins)
if (*insts[ins-1].name)
writestring(buf, 1, tcol, insts[ins-1].name, 28);
else
{
writestring(buf, 1, 0x08, "( )", 4);
writenum(buf, 2, 0x08, ins, 16, 2, 0);
}
/*
writestring(buf, 30, ci.notehit?tcolr:tcol, plNoteStr[ci.note], 3);
writestring(buf, 33, tcol, ci.pitchslide?" \x18\x19\x0D\x18\x19\x0D"+ci.pitchslide:" ~≡"+ci.pitchfx, 1);
writenum(buf, 35, tcol, ci.vol, 16, 2, 0);
writestring(buf, 37, tcol, ci.volslide?" \x18\x19\x18\x19"+ci.volslide:" ~"+ci.volfx, 1);
writestring(buf, 39, tcol, "L123456MM9ABCDER"+(ci.pan>>4), 1);
writestring(buf, 40, tcol, " \x1A\x1B"+ci.panslide, 1);
char *fxstr=getfxstr15(ci.fx);
if (fxstr)
writestring(buf, 42, tcol, fxstr, 15);
*/
drawvolbar(buf+59, i, st);
break;
case 128:
if (ins)
if (*insts[ins-1].name)
writestring(buf, 1, tcol, insts[ins-1].name, 28);
else
{
writestring(buf, 1, 0x08, "( )", 4);
writenum(buf, 2, 0x08, ins, 16, 2, 0);
}
if (smp!=0xFFFF)
if (*samps[smp].name)
writestring(buf, 31, tcol, samps[smp].name, 17);
else
{
writestring(buf, 31, 0x08, "( )", 6);
writenum(buf, 32, 0x08, smp, 16, 4, 0);
}
/*
writestring(buf, 50, ci.notehit?tcolr:tcol, plNoteStr[ci.note], 3);
writestring(buf, 53, tcol, ci.pitchslide?" \x18\x19\x0D\x18\x19\x0D"+ci.pitchslide:" ~≡"+ci.pitchfx, 1);
writenum(buf, 55, tcol, ci.vol, 16, 2, 0);
writestring(buf, 57, tcol, ci.volslide?" \x18\x19\x18\x19"+ci.volslide:" ~"+ci.volfx, 1);
writestring(buf, 59, tcol, "L123456MM9ABCDER"+(ci.pan>>4), 1);
writestring(buf, 60, tcol, " \x1A\x1B"+ci.panslide, 1);
char *fxstr=getfxstr15(ci.fx);
if (fxstr)
writestring(buf, 62, tcol, fxstr, 15);
*/
drawlongvolbar(buf+80, i, st);
break;
case 44:
writenum(buf, 1, tcol, xmpGetChanIns(i), 16, 2, 0);
/*
writestring(buf, 5, ci.notehit?tcolr:tcol, plNoteStr[ci.note], 3);
writestring(buf, 8, tcol, ci.pitchslide?" \x18\x19\x0D\x18\x19\x0D"+ci.pitchslide:" ~≡"+ci.pitchfx, 1);
writenum(buf, 10, tcol, ci.vol, 16, 2, 0);
writestring(buf, 12, tcol, ci.volslide?" \x18\x19\x18\x19"+ci.volslide:" ~"+ci.volfx, 1);
writestring(buf, 14, tcol, "L123456MM9ABCDER"+(ci.pan>>4), 1);
writestring(buf, 15, tcol, " \x1A\x1B"+ci.panslide, 1);
char *fxstr=getfxstr6(ci.fx);
if (fxstr)
writestring(buf, 17, tcol, fxstr, 6);
*/
drawvolbar(buf+26, i, st);
break;
}
}
//************************************************************************
static int xmpGetDots(notedotsdata *d, int max)
{
int pos=0;
int i,j;
for (i=0; i<plNLChan; i++)
{
if (pos>=max)
break;
int smp,frq,voll,volr,sus;
if (!xmpGetDotsData(i, smp, frq, voll, volr, sus))
continue;
d[pos].voll=voll;
d[pos].volr=volr;
d[pos].chan=i;
d[pos].note=frq;
d[pos].col=(sus?32:16)+(smp&15);//sustain
pos++;
}
return pos;
}
static int xmpOpenFile(const char *path, moduleinfostruct &info, binfile *file)
{
if (!mcpOpenPlayer)
return errGen;
if (!file)
return errFileOpen;
int (*loader)(xmodule &, binfile &)=0;
switch (info.modtype)
{
case mtXM: loader=xmpLoadModule; break;
case mtMOD: loader=xmpLoadMOD; break;
}
if (!loader)
return errFormStruc;
int retval=loader(mod, *file);
if (retval)
xmpFreeModule(mod);
file->close();
if (retval)
return -1;
insts=mod.instruments;
samps=mod.samples;
plNLChan=mod.nchan;
plIsEnd=xmpLooped;
plIdle=xmpIdle;
plProcessKey=xmpProcessKey;
plDrawGStrings=xmpDrawGStrings;
plSetMute=xmpMute;
plGetRealMasterVolume=mcpGetRealMasterVolume;
plGetMasterSample=mcpGetMasterSample;
plGetLChanSample=xmpGetLChanSample;
plGetPChanSample=mcpGetChanSample;
plUseDots(xmpGetDots);
plUseChannels(drawchannel);
gmdInstSetup(mod.instruments, mod.ninst, mod.samples, mod.nsamp, mod.sampleinfos, mod.nsampi, 0, xmpMarkInsSamp);
cpiTextRegisterMode(&xmpTrakMode);
mcpNormalize();
if (!xmpPlayModule(mod))
retval=errPlay;
plNPChan=mcpNChan;
if (retval)
{
xmpFreeModule(mod);
return retval;
}
plPause=0;
mcpSet(-1, mcpMasterPause, 0);
return errOk;
}
extern "C"
{
cpifaceplayerstruct xmpPlayer = {xmpOpenFile, xmpCloseFile};
};